﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace org.mayb.Fixtures
{
    public class ArrayInfo
    {
        private List<object> values = new List<object>();

        public void Add(object obj)
        {
            values.Add(obj);
        }

        public int Count { get { return values.Count; } }

        internal void FindRefs(List<string> refs)
        {
            foreach (object value in values)
            {
                if(value is ObjectReference)
                {
                    refs.Add(((ObjectReference)value).Reference);
                }
                else if(value is ArrayInfo)
                {
                    ((ArrayInfo)value).FindRefs(refs);
                }
                else if(value is PropertyHash)
                {
                    ((PropertyHash)value).FindRefs(refs);
                }
            }
        }

        internal void ProcessArray(object collection, Type valueType)
        {
            Type collectionType = collection.GetType();
            MethodInfo mi = collectionType.GetMethod("Add");

            if (mi == null)
                throw new FixtureException(string.Format("Type {0} does not have an 'Add' method. Cannot be treated as a collection.", collectionType.Name));

            foreach (object value in values)
            {
                if (value.GetType() == typeof(string))
                {
                    object val = Fixtures.GetTypedValue(valueType, (string)value);
                    mi.Invoke(collection, new object[] { val });
                }
                else if (value.GetType() == typeof(ObjectReference))
                {
                    object val = Fixtures.GetFixture(((ObjectReference)value).Reference);
                    if (val.GetType() == valueType || val.GetType().IsSubclassOf(valueType))
                        mi.Invoke(collection, new object[] { val });
                    else
                        throw new FixtureException(string.Format("Unable to add object of type {0} to collection with type {1}", val.GetType().Name, collectionType.Name));
                }
                //TODO: Add support for search types (and perhaps nested arrays).
            }
        }

        internal void ProcessArray(Array collection, Type valueType)
        {
            //TODO: Add support for basic arrays
        }
    }
}
